 package srdb.migration.dbhandler.enterprisedb;
 
   
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileReader;
 import java.io.InputStream;
 import java.sql.Array;
 import java.sql.Connection;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.Hashtable;
 import java.util.List;
 import java.util.regex.Matcher;
import java.util.regex.Pattern;

import srdb.migration.MTKException;
import srdb.migration.MigrationToolkit;
import srdb.migration.common.IMTKConnection;
import srdb.migration.dbhandler.srdb.Data;
 
 public class NZData extends Data
 {
   private Hashtable remoteTableNames = new Hashtable();
   private PreparedStatement psRelOptions = null;
   private static final String sqlRelOptions = "SELECT reloptions FROM sr_catalog.sr_class WHERE oid = ?::sr_catalog.regclass;";
   private long badRecordsCount = 0L;
 
   public NZData(IMTKConnection conn, int cpBatchSize)
   {
     super(conn, cpBatchSize);
   }
 
   public void setTableData(String tableName, InputStream pis, char copyDelimiter)
     throws Exception
   {
     this.badRecordsCount = 0L;
 
     List args = new ArrayList();
     args.add("nzload");
 
     Hashtable options = MigrationToolkit.getNZOptions();
 
     String remoteTableName = getRemoteTableName(tableName);
 
     if (remoteTableName != null) {
       tableName = remoteTableName;
     }
 
     options.put("t", tableName);
     Enumeration keys = options.keys();
     while (keys.hasMoreElements()) {
       String key = (String)keys.nextElement();
       Object val = options.get(key);
       args.add("-" + key);
       if ((val != null) && (((String)val).length() > 0)) {
         args.add((String)val);
       }
     }
 
     ProcessBuilder pb = new ProcessBuilder(args);
 
     Process p = pb.start();
     StreamRedirector redirect = new StreamRedirector(pis, p.getOutputStream());
     StreamGobbler sg = new StreamGobbler(p.getInputStream(), "nzload :", "out");
     StreamGobbler sg1 = new StreamGobbler(p.getErrorStream(), "nzload :", "error");
     redirect.start();
     sg.start();
     sg1.start();
     p.waitFor();
     try
     {
       sg.join();
     } catch (Exception e) {
     }
     try {
       sg1.join();
     } catch (Exception e) {
     }
     try {
       redirect.join();
     } catch (Exception e) {
     }
     if ((sg.errorFlag) || (sg1.errorFlag) || (redirect.errorFlag)) {
       throw new MTKException("nzload: An error occurred while loading data to NPS server. See log files for more details.");
     }
 
     if (options.get("maxerrors") != null)
     {
       String logFile = null;
       String outputDir = ".";
 
       if (options.get("lf") != null)
         logFile = (String)options.get("lf");
       else if (options.get("db") != null) {
         logFile = tableName + "." + options.get("db") + ".nzlog";
       }
 
       if (options.get("outputdir") != null) {
         outputDir = (String)options.get("outputdir");
       }
 
       String badRecords = "";
       try
       {
         FileReader reader = new FileReader(new File(outputDir, logFile));
         BufferedReader br = new BufferedReader(reader);
         String line = null;
         while ((line = br.readLine()) != null) {
           line = line.trim();
           if (line.startsWith("Load started at:")) {
             badRecords = ""; continue;
           }
           if (line.startsWith("number of bad records:")) {
             badRecords = line;
           }
 
         }
 
         if (badRecords.trim().length() > 0) {
           Pattern badCountPtrn = Pattern.compile("number of bad records:\\s+([0-9]+)", 42);
           Matcher badCountMatcher = badCountPtrn.matcher(badRecords);
           if (badCountMatcher.matches()) {
             this.badRecordsCount = Long.parseLong(badCountMatcher.group(1));
           }
         }
 
         br.close();
         reader.close();
       }
       catch (Exception exp)
       {
       }
     }
   }
 
   public int setTableDataViaDBLinkOra(String tableName, String targetSchema, String targetTable, boolean truncate) throws SQLException {
     throw new RuntimeException("Not supported.");
   }
 
   private String getRemoteTableName(String tableName) throws SQLException
   {
     String remoteTableName = (String)this.remoteTableNames.get(tableName);
 
     if (remoteTableName == null)
     {
       ResultSet rsRelOptions = null;
       try
       {
         if (this.psRelOptions == null) {
           this.psRelOptions = this.conn.getConnection().prepareStatement("SELECT reloptions FROM sr_catalog.sr_class WHERE oid = ?::sr_catalog.regclass;");
         }
 
         this.psRelOptions.clearParameters();
         this.psRelOptions.setString(1, tableName);
         rsRelOptions = this.psRelOptions.executeQuery();
 
         if (rsRelOptions.next()) {
           Array arrRelOptions = rsRelOptions.getArray("reloptions");
           String[] relOptions = (String[])(String[])arrRelOptions.getArray();
 
           for (String relOption : relOptions) {
             if (relOption.toLowerCase().startsWith("table")) {
               remoteTableName = relOption.split("=")[1];
               break;
             }
           }
 
           this.remoteTableNames.put(tableName, remoteTableName);
         }
       }
       finally {
         if (rsRelOptions != null) {
           rsRelOptions.close();
         }
       }
     }
 
     return remoteTableName;
   }
 
   public long getBadRows() {
     return this.badRecordsCount;
   }
 }

/* 

 * 
 */